package com.healthy_software.service.Impl;

import com.healthy_software.api.LLMClient;
import com.healthy_software.entity.*;
import com.healthy_software.dto.HealthPlanDTO;
import com.healthy_software.mapper.*;
import com.healthy_software.result.Result;
import com.healthy_software.service.HealthAdviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

@Service
public class HealthAdviceServiceImpl implements HealthAdviceService {

    @Autowired
    private MealSuggestionMapper mealSuggestionMapper;

    @Autowired
    private NutrientMapper nutrientMapper;

    @Autowired
    private GoalMapper goalMapper;

    @Autowired
    private GoalDetailsMapper goalDetailsMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LLMClient llmClient;

    @Override
    public Result<HealthPlanDTO> getHealthPlanByGoalId(Long goalId) {
        // 1. 查询目标基本信息
        Goal goal = goalMapper.selectById(goalId);
        // 2. 查询目标详情
        GoalDetail goalDetail = goalDetailsMapper.getGoalsDetailsByGoal(goalId.intValue());
        Integer goalDetailId = goalDetail.getId();
        // 3. 查询用户信息
        User user = userMapper.selectById(goal.getUserId());

        // 4. 构建LLM提示词
        String prompt = buildPrompt(goal, goalDetail, user);

        // 5. 调用LLM生成计划
        String llmResponse = llmClient.queryLLM(prompt);

        // 6. 解析LLM响应为DTO
        HealthPlanDTO healthPlan = llmClient.parseHealthPlanResponse(llmResponse);

        // 7. 初始化基础信息
        healthPlan.initBaseInfo(user.getId().toString());
        // 补充目标名称（假设goals表后续会添加goal_name字段，当前用类型+状态拼接）
        healthPlan.set目标名称(goal.getType() + "_" + goal.getStatus() + "_plan");
        // 补充目标描述（假设后续goals表添加ai_summary_description字段）
        healthPlan.set目标描述("基于您的健康目标生成的个性化计划");

        saveNutrientData(healthPlan, goalDetailId);

        return Result.success(healthPlan);
    }


    /**
     * 保存营养数据到数据库
     */
    private void saveNutrientData(HealthPlanDTO healthPlan, Integer goalDetailId) {
        // 遍历饮食目标中的餐次建议
        if (healthPlan.get饮食目标() != null) {
            healthPlan.get饮食目标().forEach(dietGoal -> {
                if (dietGoal.get具体餐次建议() != null) {
                    dietGoal.get具体餐次建议().forEach(mealSuggestionDTO -> {
                        // 1. 保存餐次建议
                        MealSuggestion mealSuggestion = new MealSuggestion()
                                .setMealType(mealSuggestionDTO.get餐次())
                                .setFoodSource(mealSuggestionDTO.get食物来源_场景())
                                .setGoalDetailId(goalDetailId)
                                .setCreateTime(LocalDateTime.now());
                        mealSuggestionMapper.insert(mealSuggestion);

                        // 2. 保存营养元素（关联当前餐次建议ID）
                        if (mealSuggestionDTO.get建议营养元素份量() != null) {
                            mealSuggestionDTO.get建议营养元素份量().forEach(nutrientDTO -> {
                                Nutrient nutrient = new Nutrient()
                                        .set卡路里(nutrientDTO.get卡路里())
                                        .set蛋白质(nutrientDTO.get蛋白质())
                                        .set脂肪(nutrientDTO.get脂肪())
                                        .set碳水化合物(nutrientDTO.get碳水化合物())
                                        .setMealSuggestionId(mealSuggestion.getId())
                                        .setCreateTime(LocalDateTime.now());
                                nutrientMapper.insert(nutrient);
                            });
                        }
                    });
                }
            });
        }
    }

    // 构建提示词（根据目标和用户信息）
    private String buildPrompt(Goal goal, GoalDetail detail, User user) {
        return String.format("""
        请根据以下用户信息和健康目标，生成符合JSON格式的健康计划（不要额外解释）。
        
        ### 用户信息：
        - 性别：%s
        - 年龄：%d（根据生日计算）
        - 身高：%s cm
        - 体重：%s kg
        
        ### 健康目标：
        - 目标类型：%s
        - 状态：%s
        - 开始时间：%s
        - 结束时间：%s
        - 每周频率：%d 天
        - 每次时长：%d 分钟
        - 饮食类型：%s
        - 目标卡路里：%d 千卡
        - 冥想时间：%s
        - 是否追踪情绪：%s
        
        ### 必须返回JSON格式，结构如下：
        {
          "运动目标": [
            {
              "目标ID": "exercise_xxx",
              "目标标题": "...",
              "具体内容": "...",
              "推荐强度": "light|moderate|vigorous",
              "推荐频率": "每周x次",
              "推荐时长_分钟": x,
              "计量单位": "分钟",
              "默认值": x,
              "预期效果": "...",
              "注意事项": "..."
            }
          ],
          "饮食目标": [
            {
              "目标ID": "diet_xxx",
              "目标标题": "...",
              "具体内容": "...",
              "推荐餐次": "一日三餐",
              "推荐频率": "每日",
              "预期效果": "...",
              "注意事项": "...",
              "具体餐次建议": [
                {
                  "餐次": "breakfast|lunch|dinner|snack",
                  "食物来源_场景": "...",
                  "建议营养元素份量": [
                    {"卡路里": x, "蛋白质": x, "脂肪": x, "碳水化合物": x}
                  ],
                  "建议食物": [
                    {"名称": "...", "份量": "...", "卡路里_估算": x, "应季": true|false}
                  ]
                }
              ]
            }
          ],
          "心理目标": [
            {
              "目标ID": "mental_xxx",
              "目标标题": "...",
              "具体内容": "...",
              "推荐频率": "每日",
              "推荐时长_分钟": x,
              "计量单位": "分钟",
              "默认值": x,
              "预期效果": "...",
              "注意事项": "..."
            }
          ]
        }
        """,
                user.getGender(),
                calculateAge(user.getBirthday()),
                user.getHeight(),
                user.getWeight(),
                goal.getType(),
                goal.getStatus(),
                goal.getStartDate(),
                goal.getEndDate(),
                detail.getDaysPerWeek(),
                detail.getDurationPerDay(),
                detail.getDietType(),
                detail.getTargetCalories(),
                detail.getMeditationTime(),
                detail.getMoodTrackingEnabled() == 1 ? "是" : "否"
        );
    }

    // 计算年龄
    private int calculateAge(java.util.Date birthday) {
        if (birthday == null) return 0;
        java.util.Calendar cal = java.util.Calendar.getInstance();
        cal.setTime(birthday);
        int birthYear = cal.get(java.util.Calendar.YEAR);
        int currentYear = java.util.Calendar.getInstance().get(java.util.Calendar.YEAR);
        return currentYear - birthYear;
    }
}